在 React 裡,你常常聽到「不要直接修改 state」。
真正的原因是:React 偵測不到你直接改了內容。
React 的運作方式是:
所以 React 不會深度比對物件的每個欄位,只會檢查「你是不是給了我一個新值或新的 reference」。
const [count, setCount] = useState(0);
// 更新為新值 → React 偵測到改變 → re-render
setCount(1);
// 設定成相同的值 → React 偵測不到改變 → 不 re-render
setCount(1);
👉 對 primitive 來說,這樣很直觀:值不同就 re-render,值相同就跳過。
const [user, setUser] = useState({ name: "Andy" });
// ❌ 錯誤:直接修改
user.name = "Jack";
setUser(user); // reference 沒變 → React 偵測不到 → 不 re-render
// ✅ 正確:建立新物件
setUser({ ...user, name: "Jack" }); // 新 reference → React 偵測到 → re-render
👉 對 reference 來說,React 只比較 reference(物件位址)。
如果你只是改了裡面的屬性,reference 沒變,React 會覺得「沒改」。
React.memo
)。setTodos([...todos, newTodo])
setUser({ ...user, age: 26 })
中文
React 判斷 state 是否改變,是透過比較值或 reference。
Primitive 值不同就 re-render;值相同就跳過。
物件/陣列只看 reference,如果直接改內容 reference 沒變,React 偵測不到。
所以我們要用不可變語法,建立新物件或陣列,確保 React 偵測到變化。